package cn.yiufung.structure.list.array;


import java.util.function.Consumer;

/**
 * 数组
 * @author 姚锋
 * @createTime 2024年07月05日 14:57:00
 */
public class MyArrayList<E> {

    private Object[] arr;

    /**
     * 默认初始化长度
     */
    private static final int INIT_LENGTH = 16;

    /**
     * 当前长度
     */
    private int size;

    /**
     * 扩容倍数
     */
    private final static int TIMES = 2;

    public MyArrayList() {
        this(INIT_LENGTH);
    }

    public MyArrayList(int initLength){
        if(initLength < 1){
            throw new RuntimeException("初始化大小异常");
        }
        this.arr = new Object[initLength];
    }

    /**
     * 添加元素
     * @param e
     */
    public void add(E e){
        if(size >= arr.length){
            this.expand();
        }
        arr[size++] = e;
    }

    /**
     * 添加元素到指定位置
     * @param e 添加元素
     * @param i 指定索引
     */
    public void add(E e, int i){
        if(i < 0 || i > size){
            throw new IndexOutOfBoundsException("下标越界");
        }
        if(size >= arr.length){
            this.expand();
        }
        for(int j = size; j > i; j--){
            arr[j] = arr[j-1];
        }
        arr[i] = e;
        size++;
    }

    /**
     * 扩容
     */
    private void expand(){
        Object[] newArr = new Object[arr.length * TIMES];
        System.arraycopy(arr, 0, newArr, 0, arr.length);
        arr = newArr;
    }

    /**
     * 删除指定元素第一个
     * @param e
     * @return
     */
    public E remove(E e){
        E removeElement = null;
        int i = 0;
        for(; i < size; i++){
            if(arr[i].equals(e)){
                removeElement = (E)arr[i];
                break;
            }
        }
        size--;
        for(int j = i; j < size; j++){
            arr[j] = arr[j+1];
        }
        return removeElement;
    }

    public E remove(int i){
        if(i >= size || i < 0){
            throw new IndexOutOfBoundsException("下标越界");
        }
        E e = (E) arr[i];
        size--;
        for(int j = i; j < size; j++){
            arr[j] = arr[j+1];
        }
        return e;
    }

    public void show(){
        forEach(System.out::println);
    }

    public void forEach(Consumer<E> consumer){
        for(int i = 0; i < size; i++){
            consumer.accept((E) arr[i]);
        }
    }

}
